﻿using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Principal;

namespace System.AutoUpdate.Extensions
{
    public class DirectoryExtensions
    {
        public static bool CanWrite (string directoryPath)
        {
            DirectoryInfo di = new DirectoryInfo (directoryPath);

            if ((di.Attributes & FileAttributes.ReadOnly) != 0)
            {
                return false;
            }

            // Get the access rules of the specified files (user groups and user names that have access to the file)
            AuthorizationRuleCollection rules = Directory.GetAccessControl (directoryPath).GetAccessRules (true, true, typeof (SecurityIdentifier));

            // Get the identity of the current user and the groups that the user is in.
            WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent ();

            if (windowsIdentity != null)
            {
                IdentityReferenceCollection groups = windowsIdentity.Groups;
                if (windowsIdentity.User != null)
                {
                    string sidCurrentUser = windowsIdentity.User.Value;

                    // Check if writing to the file is explicitly denied for this user or a group the user is in.
                    return !rules.OfType<FileSystemAccessRule> ().Any (r => groups != null && ((groups.Contains (r.IdentityReference) || r.IdentityReference.Value == sidCurrentUser) && r.AccessControlType == AccessControlType.Deny && (r.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData)) && rules.OfType<FileSystemAccessRule> ().Any (r => groups != null && ((groups.Contains (r.IdentityReference) || r.IdentityReference.Value == sidCurrentUser) && r.AccessControlType == AccessControlType.Allow && (r.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData));

                    // Check if writing is allowed
                }
            }

            return false;
        }
    }
}